/*******************************************************************************
  * 文件：Displayboard.c
  * 作者：djy
  * 版本：v1.0.0
  * 日期：2020.12.01
  * 说明：显示板驱动程序
*******************************************************************************/
#include "DisplayBoard.h"
#include "TM1629B.h"
#include "KeyCheck.h"
#include "OS_Timer.h"

/* 变量定义 *********************************************************************/
static Timer_ts sTestTimer;
volatile static DisplayRegData_ts sDisplayRegData; // 写入显示寄存器的数据
// 数码管段选表 0-9:0-9，10:数码管灭，11：E，12：n，13：t，14：s
const static U8 au8SegData[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
                                0x00,0x79,0x54,0x78,0x6d};

/* 宏定义 *********************************************************************/
#define  LEFT_SMG_A     sDisplayRegData.uGrid4_OddByte.sDisplayRegOddByte.bSEG14
#define  LEFT_SMG_B     sDisplayRegData.uGrid3_OddByte.sDisplayRegOddByte.bSEG14
#define  LEFT_SMG_C     sDisplayRegData.uGrid2_OddByte.sDisplayRegOddByte.bSEG14         
#define  LEFT_SMG_D     sDisplayRegData.uGrid1_OddByte.sDisplayRegOddByte.bSEG14   
#define  LEFT_SMG_E     sDisplayRegData.uGrid5_OddByte.sDisplayRegOddByte.bSEG14  
#define  LEFT_SMG_F     sDisplayRegData.uGrid6_OddByte.sDisplayRegOddByte.bSEG14  
#define  LEFT_SMG_G     sDisplayRegData.uGrid7_OddByte.sDisplayRegOddByte.bSEG14  
#define  LEFT_SMG_H     sDisplayRegData.uGrid8_OddByte.sDisplayRegOddByte.bSEG14  

#define  MID_SMG_A      sDisplayRegData.uGrid4_OddByte.sDisplayRegOddByte.bSEG13
#define  MID_SMG_B      sDisplayRegData.uGrid3_OddByte.sDisplayRegOddByte.bSEG13
#define  MID_SMG_C      sDisplayRegData.uGrid2_OddByte.sDisplayRegOddByte.bSEG13       
#define  MID_SMG_D      sDisplayRegData.uGrid1_OddByte.sDisplayRegOddByte.bSEG13  
#define  MID_SMG_E      sDisplayRegData.uGrid5_OddByte.sDisplayRegOddByte.bSEG13  
#define  MID_SMG_F      sDisplayRegData.uGrid6_OddByte.sDisplayRegOddByte.bSEG13  
#define  MID_SMG_G      sDisplayRegData.uGrid7_OddByte.sDisplayRegOddByte.bSEG13 
#define  MID_SMG_H      sDisplayRegData.uGrid8_OddByte.sDisplayRegOddByte.bSEG13 

#define  RIGHT_SMG_A    sDisplayRegData.uGrid4_OddByte.sDisplayRegOddByte.bSEG12
#define  RIGHT_SMG_B    sDisplayRegData.uGrid3_OddByte.sDisplayRegOddByte.bSEG12
#define  RIGHT_SMG_C    sDisplayRegData.uGrid2_OddByte.sDisplayRegOddByte.bSEG12       
#define  RIGHT_SMG_D    sDisplayRegData.uGrid1_OddByte.sDisplayRegOddByte.bSEG12  
#define  RIGHT_SMG_E    sDisplayRegData.uGrid5_OddByte.sDisplayRegOddByte.bSEG12  
#define  RIGHT_SMG_F    sDisplayRegData.uGrid6_OddByte.sDisplayRegOddByte.bSEG12  
#define  RIGHT_SMG_G    sDisplayRegData.uGrid7_OddByte.sDisplayRegOddByte.bSEG12 
#define  RIGHT_SMG_H    sDisplayRegData.uGrid8_OddByte.sDisplayRegOddByte.bSEG12 

/*******************************************************************************
  * 函数名  ：LeftSMG_Show
  * 功  能  ：左数码管显示
  * 参  数  ：U8 u8Data：显示0-9
  * 返回值  ：无
  * 说  明  ：使用共阴极段选表，显示0-9
*******************************************************************************/
static void LeftSMG_Show(U8 u8Data)
{
    if(u8Data > (ARRAY_SIZE(au8SegData)-1))
    {
        return ;
    }
    
    U8 u8SegData = au8SegData[u8Data];

    LEFT_SMG_A = u8SegData&0x01; //seg a
    u8SegData >>= 1;
    LEFT_SMG_B = u8SegData&0x01; //seg b
    u8SegData >>= 1;
    LEFT_SMG_C = u8SegData&0x01; //seg c
    u8SegData >>= 1;
    LEFT_SMG_D = u8SegData&0x01; //seg d
    u8SegData >>= 1;
    LEFT_SMG_E = u8SegData&0x01; //seg e
    u8SegData >>= 1;
    LEFT_SMG_F = u8SegData&0x01; //seg f
    u8SegData >>= 1;
    LEFT_SMG_G = u8SegData&0x01; //seg g
    u8SegData >>= 1;
}

/*******************************************************************************
  * 函数名  ：RightSMG_Show
  * 功  能  ：右数码管显示
  * 参  数  ：U8 u8Data：显示0-9
  * 返回值  ：无
  * 说  明  ：使用共阴极段选表，显示0-9
*******************************************************************************/
static void RightSMG_Show(U8 u8Data)
{
    if(u8Data > (ARRAY_SIZE(au8SegData)-1))
    {
        return ;
    }
    
    U8 u8SegData = au8SegData[u8Data];

    RIGHT_SMG_A = u8SegData&0x01; //seg a
    u8SegData >>= 1;
    RIGHT_SMG_B = u8SegData&0x01; //seg b
    u8SegData >>= 1;
    RIGHT_SMG_C = u8SegData&0x01; //seg c
    u8SegData >>= 1;
    RIGHT_SMG_D = u8SegData&0x01; //seg d
    u8SegData >>= 1;
    RIGHT_SMG_E = u8SegData&0x01; //seg e
    u8SegData >>= 1;
    RIGHT_SMG_F = u8SegData&0x01; //seg f
    u8SegData >>= 1;
    RIGHT_SMG_G = u8SegData&0x01; //seg g
    u8SegData >>= 1;
}

/*******************************************************************************
  * 函数名  ：MidSMG_Show
  * 功  能  ：中数码管显示
  * 参  数  ：U8 u8Data：显示0-9
  * 返回值  ：无
  * 说  明  ：使用共阴极段选表，显示0-9
*******************************************************************************/
static void MidSMG_Show(U8 u8Data)
{
    if(u8Data > (ARRAY_SIZE(au8SegData)-1))
    {
        return ;
    }

    U8 u8SegData = au8SegData[u8Data];

    MID_SMG_A = u8SegData&0x01; //seg a
    u8SegData >>= 1;
    MID_SMG_B = u8SegData&0x01; //seg b
    u8SegData >>= 1;
    MID_SMG_C = u8SegData&0x01; //seg c
    u8SegData >>= 1;
    MID_SMG_D = u8SegData&0x01; //seg d
    u8SegData >>= 1;
    MID_SMG_E = u8SegData&0x01; //seg e
    u8SegData >>= 1;
    MID_SMG_F = u8SegData&0x01; //seg f
    u8SegData >>= 1;
    MID_SMG_G = u8SegData&0x01; //seg g
    u8SegData >>= 1;
}

/*******************************************************************************
  * 函数名  ：SMG_AllOff
  * 功  能  ：三个数码管全部熄灭
  * 参  数  ：无
  * 返回值  ：无
  * 说  明  ：使用共阴极段选表，index = [10]
*******************************************************************************/
void SMG_AllOff(void)
{
    RightSMG_Show(10);
    MidSMG_Show(10);
    LeftSMG_Show(10);
}

/*******************************************************************************
  * 函数名  ：SMG_ShowNum
  * 功  能  ：三个数码管显示数字
  * 参  数  ：U8 u8Data：显示0-999
  * 返回值  ：无
  * 说  明  ：使用共阴极段选表，显示0-9
*******************************************************************************/
void SMG_ShowNum(U16 u16Data)
{
    // 0-9
    if(u16Data <= 9)
    {
        // 右数码管显示个位0-9
        RightSMG_Show(u16Data);
        // 中数码管不显示
        MidSMG_Show(10);
        // 左数码管不显示
        LeftSMG_Show(10);
    }
    // 10-99
    else if(u16Data <= 99)
    {
        // 右数码管显示个位
        RightSMG_Show(u16Data%10);
        // 中数码管显示十位
        MidSMG_Show((u16Data/10));
        // 左数码管不显示
        LeftSMG_Show(10);
    }
    // 100 - 999
    else if(u16Data <= 999)
    {
        // 右数码管显示个位
        RightSMG_Show(u16Data%10);
        // 中数码管显示十位
        MidSMG_Show((u16Data/10)%10);
        // 左数码管显示百位
        LeftSMG_Show((u16Data/100)%10);   
    }

}

/*******************************************************************************
  * 函数名  ：SMG_ShowSymbol
  * 功  能  ：三个数码管显示符号
  * 参  数  ：U8 u8Data：显示0-999
  * 返回值  ：无
  * 说  明  ：使用共阴极段选表，显示0-9
*******************************************************************************/
void SMG_ShowSymbol(Symbol_te eSymbol)
{
    switch (eSymbol)
    {
    case eEN:
        LeftSMG_Show(10);
        MidSMG_Show(11);
        RightSMG_Show(12);
    break;
    case eE1:
        LeftSMG_Show(10);
        MidSMG_Show(11);
        RightSMG_Show(1);
    break;
    case eE2:
        LeftSMG_Show(10);
        MidSMG_Show(11);
        RightSMG_Show(2);
    break;
	case eE4:
        LeftSMG_Show(10);
        MidSMG_Show(11);
        RightSMG_Show(4);
    break;
    case eE5:
        LeftSMG_Show(10);
        MidSMG_Show(11);
        RightSMG_Show(5);
    break;
    case eE6:
        LeftSMG_Show(10);
        MidSMG_Show(11);
        RightSMG_Show(6);
    break;
    case eTST:
        LeftSMG_Show(13);
        MidSMG_Show(14);
        RightSMG_Show(13);
    break;
    default:
    break;
    }
}

/*******************************************************************************
  * 函数名  ：SMG_IconTemper
  * 功  能  ：数码管显示温度ICON
  * 参  数  ：Bool bState:1开启      0关闭 
  * 返回值  ：无
  * 说  明  ：温度ICON使用中数码管H段控制
*******************************************************************************/
void SMG_IconTemper(Bool bState)
{
    if(bState)
    {
        MID_SMG_H = 1;
    }
    else
    {
        MID_SMG_H = 0;
    }
}

/*******************************************************************************
  * 函数名  ：SMG_IconMinute
  * 功  能  ：数码管显示分钟ICON
  * 参  数  ：Bool bState:1开启      0关闭 
  * 返回值  ：无
  * 说  明  ：分钟ICON使用右数码管H段控制
*******************************************************************************/
void SMG_IconMinute(Bool bState)
{
    if(bState)
    {
        RIGHT_SMG_H = 1;
    }
    else
    {
        RIGHT_SMG_H = 0;
    }
}

/*******************************************************************************
  * 函数名  ：LED_WifiCtrl
  * 功  能  ：显示板wifi-LED控制
  * 参  数  ：LEDCtrl_te eState：2全亮      0关闭
  * 返回值  ：无
  * 说  明  ：WIIF-LED使用Grid2-Seg9控制，不支持半亮
*******************************************************************************/
void LED_WifiCtrl(LEDCtrl_te eState)
{
    switch (eState)
    {
    case eLED_OFF:
        sDisplayRegData.uGrid2_OddByte.sDisplayRegOddByte.bSEG9 = 0;
    break;
    case eLED_ON:
        sDisplayRegData.uGrid2_OddByte.sDisplayRegOddByte.bSEG9 = 1;
    break;
    case eLED_TOGGLE:
        if(sDisplayRegData.uGrid2_OddByte.sDisplayRegOddByte.bSEG9)
		{
			sDisplayRegData.uGrid2_OddByte.sDisplayRegOddByte.bSEG9 = 0;
		}
		else
		{
		  	sDisplayRegData.uGrid2_OddByte.sDisplayRegOddByte.bSEG9 = 1;
		}
    break;
    default:
    break;
    }
}

/*******************************************************************************
  * 函数名  ：LED_WifiCtrl
  * 功  能  ：显示板Sub-LED控制
  * 参  数  ：LEDCtrl_te eState：2全亮      0关闭
  * 返回值  ：无
  * 说  明  ：Sub-LED使用Grid4-Seg11控制，不支持半亮
*******************************************************************************/
void LED_SubCtrl(LEDCtrl_te eState)
{
    switch (eState)
    {
    case eLED_OFF:
        sDisplayRegData.uGrid4_OddByte.sDisplayRegOddByte.bSEG11 = 0;
    break;
    case eLED_ON:
        sDisplayRegData.uGrid4_OddByte.sDisplayRegOddByte.bSEG11 = 1;
    break;
    default:
    break;
    }
}

/*******************************************************************************
  * 函数名  ：LED_AddCtrl
  * 功  能  ：显示板Add-LED控制
  * 参  数  ：LEDCtrl_te eState：2全亮      0关闭
  * 返回值  ：无
  * 说  明  ：Add-LED使用Grid2-Seg11控制，不支持半亮
*******************************************************************************/
void LED_AddCtrl(LEDCtrl_te eState)
{
    switch (eState)
    {
    case eLED_OFF:
        sDisplayRegData.uGrid2_OddByte.sDisplayRegOddByte.bSEG11 = 0;
    break;
    case eLED_ON:
        sDisplayRegData.uGrid2_OddByte.sDisplayRegOddByte.bSEG11 = 1;
    break;
    default:
    break;
    }
}

/*******************************************************************************
  * 函数名  ：LED_LeftTimingCtrl
  * 功  能  ：显示板左定时-LED控制
  * 参  数  ：LEDCtrl_te eState：2全亮 1半亮       0关闭 
  * 返回值  ：无
  * 说  明  ：左定时-LED全亮使用Grid3-Seg10控制，左定时-LED半亮使用Grid1-Seg11控制
*******************************************************************************/
void LED_LeftTimingCtrl(LEDCtrl_te eState)
{
    switch (eState)
    {
    case eLED_OFF:
        // 全亮灭 
        sDisplayRegData.uGrid3_OddByte.sDisplayRegOddByte.bSEG10 = 0;
        // 半亮灭                        
        sDisplayRegData.uGrid1_OddByte.sDisplayRegOddByte.bSEG11 = 0;
    break;
    case eLED_ON:
        // 全亮开
        sDisplayRegData.uGrid3_OddByte.sDisplayRegOddByte.bSEG10 = 1;
        // 半亮灭                        
        sDisplayRegData.uGrid1_OddByte.sDisplayRegOddByte.bSEG11 = 0;
    break;
    case eLED_HALF:
        // 全亮灭
        sDisplayRegData.uGrid3_OddByte.sDisplayRegOddByte.bSEG10 = 0;
        // 半亮开
        sDisplayRegData.uGrid1_OddByte.sDisplayRegOddByte.bSEG11 = 1;
    break;
    default:
    break;
    }
}

/*******************************************************************************
  * 函数名  ：LED_RightTimingCtrl
  * 功  能  ：显示板右灶定时-LED控制
  * 参  数  ：LEDCtrl_te eState：2全亮 1半亮       0关闭 
  * 返回值  ：无
  * 说  明  ：右定时-LED全亮使用Grid2-Seg10控制，左定时-LED半亮使用Grid6-Seg11控制
*******************************************************************************/
void LED_RightTimingCtrl(LEDCtrl_te eState)
{
    switch (eState)
    {
    case eLED_OFF:
        // 全亮灭 
        sDisplayRegData.uGrid2_OddByte.sDisplayRegOddByte.bSEG10 = 0;
        // 半亮灭                        
        sDisplayRegData.uGrid6_OddByte.sDisplayRegOddByte.bSEG11 = 0;
    break;
    case eLED_ON:
        // 全亮开
        sDisplayRegData.uGrid2_OddByte.sDisplayRegOddByte.bSEG10 = 1;
        // 半亮灭                        
        sDisplayRegData.uGrid6_OddByte.sDisplayRegOddByte.bSEG11 = 0;
    break;
    case eLED_HALF:
        // 全亮灭
        sDisplayRegData.uGrid2_OddByte.sDisplayRegOddByte.bSEG10 = 0;
        // 半亮开
        sDisplayRegData.uGrid6_OddByte.sDisplayRegOddByte.bSEG11 = 1;
    break;
    default:
    break;
    }
}

/*******************************************************************************
  * 函数名  ：LED_MidTimingCtrl
  * 功  能  ：显示板中灶定时-LED控制
  * 参  数  ：LEDCtrl_te eState：2全亮 1半亮       0关闭 
  * 返回值  ：无
  * 说  明  ：中定时-LED全亮使用Grid3-Seg11控制，左定时-LED半亮使用Grid5-Seg11控制
*******************************************************************************/
void LED_MidTimingCtrl(LEDCtrl_te eState)
{
    switch (eState)
    {
    case eLED_OFF:
        // 全亮灭 
        sDisplayRegData.uGrid3_OddByte.sDisplayRegOddByte.bSEG11 = 0;
        // 半亮灭                        
        sDisplayRegData.uGrid5_OddByte.sDisplayRegOddByte.bSEG11 = 0;
    break;
    case eLED_ON:
        // 全亮开
        sDisplayRegData.uGrid3_OddByte.sDisplayRegOddByte.bSEG11 = 1;
        // 半亮灭                        
        sDisplayRegData.uGrid5_OddByte.sDisplayRegOddByte.bSEG11 = 0;
    break;
    case eLED_HALF:
        // 全亮灭
        sDisplayRegData.uGrid3_OddByte.sDisplayRegOddByte.bSEG11 = 0;
        // 半亮开
        sDisplayRegData.uGrid5_OddByte.sDisplayRegOddByte.bSEG11 = 1;
    break;
    default:
    break;
    }    
}

/*******************************************************************************
  * 函数名  ：Key_GetValue
  * 功  能  ：显示板获取按键值
  * 参  数  ：无
  * 返回值  ：无
  * 说  明  ：将TM1629的KeyByte1234分别存至u32KeyValue
*******************************************************************************/
U32 Key_GetValue(void)
{
    U32 u32KeyValue = 0;
	TM1629KeyData_ts sKeyValue;

    // 清零sKeyValue
    memset(&sKeyValue,0x00,sizeof(sKeyValue));
    
	// 读取TM1629按键寄存器
	sKeyValue = TM1629_ReadKeyData();

    // 将TM1629的KeyByte1234分别存至u32KeyValue
	u32KeyValue |= sKeyValue.uByte4.u8KeyByte;
	u32KeyValue <<= 8;
	u32KeyValue |= sKeyValue.uByte3.u8KeyByte;
	u32KeyValue <<= 8;
    u32KeyValue |= sKeyValue.uByte2.u8KeyByte;
	u32KeyValue <<= 8;
    u32KeyValue |= sKeyValue.uByte1.u8KeyByte;

    return u32KeyValue;
}

/*******************************************************************************
  * 函数名  ：DisplayTask
  * 功  能  ：显示任务
  * 参  数  ：无
  * 返回值  ：无
  * 说  明  ：用地址增加模式，将显示寄存器16个字节全部更新，轮询GRID1-8。
*******************************************************************************/
static void DisplayTask(void)
{
    TM1629_WriteDisplayBytes(0x00,(U8*)&sDisplayRegData,sizeof(sDisplayRegData));
}

/*******************************************************************************
  * 函数名  ：TestSMG
  * 功  能  ：数码管测试
  * 参  数  ：无
  * 返回值  ：无
  * 说  明  ：无
*******************************************************************************/
void TestSMG(void)
{
    SMG_ShowNum(OS_TimerGetExpiredTimes(&sTestTimer));

    if(OS_TimerGetExpiredTimes(&sTestTimer)%2)
    {
        SMG_IconMinute(ON);
        SMG_IconTemper(OFF);
    }
    else
    {
        SMG_IconMinute(OFF);
        SMG_IconTemper(ON);
    }
	DisplayTask();
}

/*******************************************************************************
  * 函数名  ：DisplayBoard_Init
  * 功  能  ：显示板初始化
  * 参  数  ：无
  * 返回值  ：无
  * 说  明  ：无
*******************************************************************************/
void DisplayBoard_Init(void)
{
    // 初始化TM1629芯片
    TM1629_Init();
    
    // 显示寄存器清零
	TM1629_WriteDisplayBytes(0x00,(U8*)&sDisplayRegData,sizeof(sDisplayRegData));

	TM1629_SetBright(eBRIGHT_LEVEL_7);
	
	// 初始化按键任务
	Key_Init();
	
	// 创建显示任务
    OS_TaskCreate(DisplayTask);

    // 测试数码管
    //OS_TimerStart(&sTestTimer,500,TestSMG);
}
